use rbatis::rbdc::{DateTime, Timestamp};
use redis::{ErrorKind, FromRedisValue, RedisError, RedisResult, RedisWrite, ToRedisArgs, Value};
use serde::{Deserialize, Serialize};
use crate::domain::dto::user_dto::UserCreateRequest;

/// 用户表 a_user
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UserEntity {
    /** 主键 */
    pub id: u64,
    /** 账号 */
    pub username: String,
    /** 密码 */
    pub password: String,
    /** 用户类型：0-普通用户、1-超级管理员 */
    pub user_type: i8,
    /** 业务线权限，多个逗号分隔 */
    pub permission_biz: Option<String>,
    pub create_time: DateTime,
    pub update_time: Option<DateTime>,
    pub can_view: bool,
}

impl FromRedisValue for UserEntity {
    fn from_redis_value(v: &Value) -> RedisResult<Self> {
        match v {
            Value::BulkString(bytes) => {
                let string = String::from_utf8(bytes.clone())?;
                serde_json::from_str::<UserEntity>(string.as_str()).map_err(|e| {
                    redis::RedisError::from((ErrorKind::TypeError, "Failed to parse JSON", e.to_string()))
                })
            },
            _ => Err(RedisError::from((
                ErrorKind::ParseError,
                "Serialization Error",
            ))),
        }
    }
}

impl ToRedisArgs for UserEntity {
    fn write_redis_args<W>(&self, out: &mut W)
    where
        W: ?Sized + RedisWrite
    {
        let x = serde_json::to_string(self).map_or(String::new(), |v| v);
        let x = x.as_bytes();
        out.write_arg(x)
    }
}

impl From<UserCreateRequest> for UserEntity {
    fn from(value: UserCreateRequest) -> Self {
        Self {
            id: 0,
            username: value.username,
            password: value.password,
            user_type: value.user_type,
            permission_biz: value.permission_biz,
            create_time: DateTime::now(),
            update_time: None,
            can_view: true,
        }
    }
}